<template>
    <div class="gradient-container">
        <canvas ref="canvasRef" class="gradient-background"></canvas>
    </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue';

const canvasRef = ref(null);
let animationFrameId:any = null;

// 生成随机颜色
const getRandomColor = () => {
    const hue = Math.random() * 360;
    return `hsl(${hue}, 70%, 70%)`;
};

// 初始化颜色
let currentColors = [
    getRandomColor(),
    getRandomColor(),
    getRandomColor(),
    getRandomColor()
];

let targetColors = [
    getRandomColor(),
    getRandomColor(),
    getRandomColor(),
    getRandomColor()
];

// 在两个颜色之间进行插值
const interpolateColor = (color1:any, color2:any, factor:any) => {
    const c1 = color1.match(/\d+/g).map(Number);
    const c2 = color2.match(/\d+/g).map(Number);

    const h = c1[0] + (c2[0] - c1[0]) * factor;
    return `hsl(${h}, 70%, 70%)`;
};

const animate = () => {
    const canvas:any = canvasRef.value;
    if(!canvas) return;
    const ctx = canvas.getContext('2d');
    let progress = 0;
    let transitionDuration = 5000; // 渐变过渡时间（毫秒）
    let startTime = Date.now();

    const updateAnimation = () => {
        const currentTime = Date.now();
        progress = (currentTime - startTime) / transitionDuration;

        if (progress >= 1) {
            currentColors = [...targetColors];
            targetColors = [
                getRandomColor(),
                getRandomColor(),
                getRandomColor(),
                getRandomColor()
            ];
            startTime = currentTime;
            progress = 0;
        }

        const gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);

        // 计算当前渐变颜色
        const interpolatedColors = currentColors.map((color, index) =>
            interpolateColor(color, targetColors[index], progress)
        );

        interpolatedColors.forEach((color, index) => {
            gradient.addColorStop(index / (interpolatedColors.length - 1), color);
        });

        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        animationFrameId = requestAnimationFrame(updateAnimation);
    };

    updateAnimation();
};

// 调整 canvas 尺寸
const resizeCanvas = () => {
    const canvas:any = canvasRef.value;
    if(!canvas) return;
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
};

onMounted(() => {
    window.addEventListener('resize', resizeCanvas);
    resizeCanvas();
    animate();
});

onBeforeUnmount(() => {
    window.removeEventListener('resize', resizeCanvas);
    if (animationFrameId) {
        cancelAnimationFrame(animationFrameId);
    }
});
</script>

<style scoped>
.gradient-container {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    /* 改为负值，确保在最底层 */
    overflow: hidden;
    margin: 0;
    padding: 0;
}

.gradient-background {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
</style>